#通过def函数自定义“新函数”
def hello(name):
 return 'Hello, ' + name + '!'
print(hello('Gumby'))#输出Hello, Gumby!

def fibs(num):
 result = [0, 1]
 for i in range(num-2): #这里-2是因为result = [0, 1]，已经有两个数字作为初始的加数
     result.append(result[-2] + result[-1])
 return result
print(fibs(10))

#来创建一个初始化数据结构的函数
def init(data):
 data['first'] = {}
 data['middle'] = {}
 data['last'] = {}

storage = {}
init(storage)#通过函数的方式创建了一个字典
print(storage)#输出为{'first': {}, 'middle': {}, 'last': {}}——在字典中，键的排列顺序是不固定的，因此打印字典时，每次的顺序都可能不同。

#创建一个获取人员姓名的函数
def lookup(data, label, name):#比如 lookup(storage, 'middle', 'Lie')，在storage中通过提供是label参数（是姓、名、中间名？）和name参数（名字），查到storage的全名
 return data[label].get(name)

# #创建将人员存储到数据结构中的函数
# def store(data, full_name):#将参数data和full_name提供给这个函数。这些参数被设置为从外部获得的值。
#  names = full_name.split()#split于将字符串拆分为序列——通过拆分full_name创建一个名为names的列表。
#  if len(names) == 2: names.insert(1, '')#如果names的长度为2（只有名字和姓），就将中间名设置为空字符串。
#  labels = 'first', 'middle', 'last'#将'first'、'middle'和'last'存储在元组labels中（也可使用列表，这里使用元组只是为了省略方括号），label的参数被定义下来
#  for label, name in zip(labels, names):# 使用函数zip将标签和对应的名字合并
#   people = lookup(data, label, name)
#   if people:
#    people.append(full_name)
#   else:
#    data[label][name] = [full_name]

#另一种定义方法
def store(data, *full_names): #在下面补充它的作用
 for full_name in full_names:
  names = full_name.split()
  if len(names) == 2: names.insert(1, '')
  labels = 'first', 'middle', 'last'
  for label, name in zip(labels, names):
   people = lookup(data, label, name)
   if people:
    people.append(full_name)
   else:
    data[label][name] = [full_name]


#测试一下上面定义函数的效果
MyNames = {}
init(MyNames)
store(MyNames, 'Magnus Lie Hetland')
store(MyNames, 'Robin Hood')
store(MyNames, 'Robin Locksley')
print(MyNames)#{'first': {'Magnus': ['Magnus Lie Hetland'], 'Robin': ['Robin Hood', 'Robin Locksley']}, 'middle': {'Lie': ['Magnus Lie Hetland'], '': ['Robin Hood', 'Robin Locksley']}, 'last': {'Hetland': ['Magnus Lie Hetland'], 'Hood': ['Robin Hood'], 'Locksley': ['Robin Locksley']}}
print(lookup(MyNames, 'middle', 'Lie'))


#第40行中*的作用——参数前面的星号将提供的所有值都放在一个元组中
#延申知识两个*，是收集关键字参数，输出的是一个字典而不再是元组
def print_params_4(x, y, z=3, *pospar, **keypar):
 print(x, y, z)
 print(pospar)
 print(keypar)

print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2)
#输出为
# 1 2 3——z=3的定位
# (5, 6, 7)
# {'foo': 1, 'bar': 2}——**开始收集关键字参数